package com.quectel.mobile.controller.partybuilding;


import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.constant.core.partybuilding.PartyBuildingConstants;
import com.quectel.constant.core.partybuilding.PartyBuildingMeetingConstants;
import com.quectel.constant.core.partybuilding.PartyBuildingPlanConstants;
import com.quectel.constant.core.partybuilding.PartySurveyConstants;
import com.quectel.constant.core.partyeducationexam.PartyEducationExamConstants;
import com.quectel.constant.core.partyeducationtraining.TrainingConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.partybuilding.dto.PartyPersonDto;
import com.quectel.core.module.partybuildingactivity.dto.PartyBuildingActivityDto;
import com.quectel.core.module.partybuildingactivity.dto.PartyBuildingActivityPersonJoinBindingDto;
import com.quectel.core.module.partybuildingactivity.service.PartyBuildingActivityService;
import com.quectel.core.module.partybuildingmeeting.dto.PartyBuildingMeetingDto;
import com.quectel.core.module.partybuildingmeeting.dto.PartyBuildingMeetingPersonBindingDto;
import com.quectel.core.module.partybuildingmeeting.service.PartyBuildingMeetingService;
import com.quectel.core.module.partybuildingsurvey.dto.PartySurveyDto;
import com.quectel.core.module.partybuildingsurvey.dto.PartySurveyPersonBindingDto;
import com.quectel.core.module.partybuildingsurvey.service.PartySurveyPersonBindingService;
import com.quectel.core.module.partybuildingtask.dto.PartyBuildingPlanTaskDto;
import com.quectel.core.module.partybuildingtask.service.PartyBuildingPlanTaskService;
import com.quectel.core.module.partyeducationexam.dto.PartyEducationTrainingExamPersonDto;
import com.quectel.core.module.partyeducationexam.dto.ref.ExamRefPersonDto;
import com.quectel.core.module.partyeducationexam.service.PartyEducationTrainingExamPersonService;
import com.quectel.core.module.partyeducationtraining.dto.TrainingDto;
import com.quectel.core.module.partyeducationtraining.dto.TrainingPersonDto;
import com.quectel.core.module.partyeducationtraining.dto.ref.TrainingRefConcourseDto;
import com.quectel.core.module.partyeducationtraining.service.TrainingPersonService;
import com.quectel.mobile.controller.BaseController;
import com.quectel.mobile.util.SessionHolder;
import com.quectel.mobile.vo.partybuilding.PartyBuildingTodoResp;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 在这里编写说明
 *
 * @author: bob
 * @email: bob.yu@quectel.com
 * @date: 2023-06-26 16:41:00
 */
@RestController
@RequestMapping("partyBuildingTodo")
@Tag(name = "PartyBuildingTodoController", description = "党建待办相关api")
public class PartyBuildingTodoController extends BaseController {

    @DubboReference
    private PartyBuildingMeetingService meetingService;
    @DubboReference
    private PartyBuildingActivityService activityService;
    @DubboReference
    private PartyBuildingPlanTaskService taskService;
    @DubboReference
    private PartySurveyPersonBindingService partySurveyPersonBindingService;
    @DubboReference
    private TrainingPersonService trainingPersonService;
    @DubboReference
    private PartyEducationTrainingExamPersonService examPersonService;

    @GetMapping("todoList")
    @Operation(summary = "待办事项, 类型type 字典值PartyBuildingTodoType: 1.在线考试...")
    public Response<List<PartyBuildingTodoResp>> todoList() {
        Date currentDate = new Date();
        SessionHolder.checkPartyPerson();
        PartyPersonDto partyPerson = Objects.requireNonNull(SessionHolder.getLoginMobileUserSession()).getPartyPerson();

        List<PartyBuildingTodoResp> resultList = new ArrayList<>();

        // 在线考试
        CompletableFuture<Void> examTraining = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            List<Byte> statuses = new ArrayList<>();
            statuses.add(PartyEducationExamConstants.StatusEnum.PUBLISHED.getStatus());
            queryMap.put(SystemConstants.STATUSES, new Byte[]{PartyEducationExamConstants.StatusEnum.PUBLISHED.getStatus()});
            queryMap.put("isLearning", 1);
            queryMap.put(LambdaUtil.getFieldName(PartyEducationTrainingExamPersonDto::getPartyPersonId),
                    partyPerson.getId());
            List<ExamRefPersonDto> result = examPersonService.queryExamList(queryMap);
            if (CollectionUtils.isNotEmpty(result)) {
                ExamRefPersonDto examRefPersonDto = result.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(examRefPersonDto.getTrainingId());
                resp.setType(PartyBuildingConstants.TodoType.PARTY_EDUCATION_QUESTION.getType());
                resp.setName(examRefPersonDto.getTraining().getName());
                resp.setStartTime(examRefPersonDto.getTraining().getStartTime());
                resp.setEndTime(examRefPersonDto.getTraining().getEndTime());
                resp.setCreateTime(examRefPersonDto.getTraining().getCreateTime());
                resultList.add(resp);
            }
        });

        // 三会一课
        CompletableFuture<Void> threeMeetingsFuture = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getCategory),
                    PartyBuildingMeetingConstants.CategoryEnum.THREE_MEETINGS_ONE_LESSON.getCategory());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingPersonBindingDto::getPartyPersonId),
                    partyPerson.getId());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getStatus),
                    PartyBuildingMeetingConstants.MeetingStatus.NOT_BEGIN.getStatus());
            List<PartyBuildingMeetingDto> partyBuildingMeetingDtos = meetingService.queryList(queryMap);
            if (CollectionUtils.isNotEmpty(partyBuildingMeetingDtos)) {
                PartyBuildingMeetingDto partyBuildingMeetingDto = partyBuildingMeetingDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(partyBuildingMeetingDto.getId());
                resp.setType(PartyBuildingConstants.TodoType.THREE_MEETINGS_ONE_LESSON.getType());
                resp.setName(partyBuildingMeetingDto.getSubject());
                resp.setStartTime(partyBuildingMeetingDto.getStartTime());
                resp.setEndTime(partyBuildingMeetingDto.getEndTime());
                resp.setCreateTime(partyBuildingMeetingDto.getCreateTime());
                resultList.add(resp);
            }
        });

        // 主题党日
        CompletableFuture<Void> themePartyDayFuture = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getCategory),
                    PartyBuildingMeetingConstants.CategoryEnum.THEME_PARTY_DAY.getCategory());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingPersonBindingDto::getPartyPersonId),
                    partyPerson.getId());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getStatus),
                    PartyBuildingMeetingConstants.MeetingStatus.NOT_BEGIN.getStatus());
            List<PartyBuildingMeetingDto> themePartyDayMeetingDtos = meetingService.queryList(queryMap);
            if (CollectionUtils.isNotEmpty(themePartyDayMeetingDtos)) {
                PartyBuildingMeetingDto partyBuildingMeetingDto = themePartyDayMeetingDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(partyBuildingMeetingDto.getId());
                resp.setType(PartyBuildingConstants.TodoType.THEME_PARTY_DAY.getType());
                resp.setName(partyBuildingMeetingDto.getSubject());
                resp.setStartTime(partyBuildingMeetingDto.getStartTime());
                resp.setEndTime(partyBuildingMeetingDto.getEndTime());
                resp.setCreateTime(partyBuildingMeetingDto.getCreateTime());
                resultList.add(resp);
            }
        });

        // 组织生活会
        CompletableFuture<Void> partyLifeMeetingFuture = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getCategory),
                    PartyBuildingMeetingConstants.CategoryEnum.PARTY_LIFE_MEETING.getCategory());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingPersonBindingDto::getPartyPersonId),
                    partyPerson.getId());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getStatus),
                    PartyBuildingMeetingConstants.MeetingStatus.NOT_BEGIN.getStatus());
            List<PartyBuildingMeetingDto> partyLifeMeetingDtos = meetingService.queryList(queryMap);
            if (CollectionUtils.isNotEmpty(partyLifeMeetingDtos)) {
                PartyBuildingMeetingDto partyBuildingMeetingDto = partyLifeMeetingDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(partyBuildingMeetingDto.getId());
                resp.setType(PartyBuildingConstants.TodoType.PARTY_LIFE_MEETING.getType());
                resp.setName(partyBuildingMeetingDto.getSubject());
                resp.setStartTime(partyBuildingMeetingDto.getStartTime());
                resp.setEndTime(partyBuildingMeetingDto.getEndTime());
                resp.setCreateTime(partyBuildingMeetingDto.getCreateTime());
                resultList.add(resp);
            }
        });

        // 主题活动
        CompletableFuture<Void> partyActivityFuture = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingActivityPersonJoinBindingDto::getPartyPersonId),
                    partyPerson.getId());
            queryMap.put("joinIn", SystemConstants.NO);
            List<PartyBuildingActivityDto> partyBuildingActivityDtos = activityService.queryListWithoutPadding(queryMap);
            if (CollectionUtils.isNotEmpty(partyBuildingActivityDtos)) {
                List<PartyBuildingActivityDto> filteredMeetings = partyBuildingActivityDtos.stream()
                        .filter(meeting -> meeting.getStatus() == 1 && currentDate.after(meeting.getActivityStartTime()))
                        .collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(filteredMeetings)){
                    PartyBuildingActivityDto activityDto = filteredMeetings.get(0);
                    PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                    resp.setId(activityDto.getId());
                    resp.setType(PartyBuildingConstants.TodoType.PARTY_ACTIVITY_BEGIN_REMIND.getType());
                    resp.setName(activityDto.getSubject());
                    resp.setStartTime(activityDto.getActivityStartTime());
                    resp.setEndTime(activityDto.getActivityEndTime());
                    resp.setCreateTime(activityDto.getCreateTime());
                    resultList.add(resp);
                }
            }
        });

        // 党建任务
        CompletableFuture<Void> partyBuildingTaskFuture = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingPlanTaskDto::getDate),
                    DateUtils.format(currentDate, DateUtils.FormatType.SIMPLE));
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingPlanTaskDto::getStatus),
                    PartyBuildingPlanConstants.TaskStatus.UNCOMPLETED.getStatus());
            queryMap.put(LambdaUtil.getFieldName(PartyBuildingPlanTaskDto::getExecUserId), partyPerson.getId());
            List<PartyBuildingPlanTaskDto> partyBuildingPlanTaskDtos = taskService.queryList(queryMap);
            if (CollectionUtils.isNotEmpty(partyBuildingPlanTaskDtos)) {
                PartyBuildingPlanTaskDto taskDto = partyBuildingPlanTaskDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(taskDto.getId());
                resp.setType(PartyBuildingConstants.TodoType.PARTY_BUILDING_TASK.getType());
                resp.setName(taskDto.getName());
                resp.setCreateTime(taskDto.getCreateTime());
                resultList.add(resp);
            }
        });

        // 在线党课
        CompletableFuture<Void> partyCourses = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(TrainingDto::getPublishStatus),
                    TrainingConstants.PublishStatusEnum.ON.getPublishStatus().toString());
            queryMap.put(LambdaUtil.getFieldName(TrainingPersonDto::getPartyPersonId), partyPerson.getId());
            queryMap.put("isLearning", 1);
            List<TrainingRefConcourseDto> trainingRefConcourseDtos = trainingPersonService.queryTrainingList(queryMap);
            if (CollectionUtils.isNotEmpty(trainingRefConcourseDtos)) {
                TrainingRefConcourseDto concourseDto = trainingRefConcourseDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(concourseDto.getId());
                resp.setType(PartyBuildingConstants.TodoType.PARTY_COURSES.getType());
                resp.setName(concourseDto.getName());
                resp.setStartTime(concourseDto.getStartTime());
                resp.setEndTime(concourseDto.getEndTime());
                resp.setCreateTime(concourseDto.getCreateTime());
                resultList.add(resp);
            }
        });

        // 民意调查
        CompletableFuture<Void> publicOpinionSurvey = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartySurveyDto::getCategory),
                    PartySurveyConstants.Category.PUBLIC_OPINION_SURVEY.getCategory());
            queryMap.put(LambdaUtil.getFieldName(PartySurveyPersonBindingDto::getPersonId), partyPerson.getId());
            queryMap.put(LambdaUtil.getFieldName(PartySurveyPersonBindingDto::getParticipateStatus), SystemConstants.NO);
            List<PartySurveyPersonBindingDto> partySurveyDtos = partySurveyPersonBindingService.queryList(queryMap);
            if (CollectionUtils.isNotEmpty(partySurveyDtos)) {
                PartySurveyPersonBindingDto surveyDto = partySurveyDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(surveyDto.getPartySurveyId());
                resp.setType(PartyBuildingConstants.TodoType.PARTY_SURVEY_PUBLIC_OPINION_SURVEY.getType());
                resp.setName(surveyDto.getPartySurveyName());
                resp.setStartTime(surveyDto.getPartySurveyStartTime());
                resp.setEndTime(surveyDto.getPartySurveyEndTime());
                resultList.add(resp);
            }
        });

        // 民主投票
        CompletableFuture<Void> democraticVoting = CompletableFuture.runAsync(() -> {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put(LambdaUtil.getFieldName(PartySurveyDto::getCategory),
                    PartySurveyConstants.Category.DEMOCRATIC_VOTING.getCategory());
            queryMap.put(LambdaUtil.getFieldName(PartySurveyPersonBindingDto::getPersonId), partyPerson.getId());
            queryMap.put(LambdaUtil.getFieldName(PartySurveyPersonBindingDto::getParticipateStatus), SystemConstants.NO);
            List<PartySurveyPersonBindingDto> democraticVotingDtos = partySurveyPersonBindingService.queryList(queryMap);
            if (CollectionUtils.isNotEmpty(democraticVotingDtos)) {
                PartySurveyPersonBindingDto surveyDto = democraticVotingDtos.get(0);
                PartyBuildingTodoResp resp = new PartyBuildingTodoResp();
                resp.setId(surveyDto.getPartySurveyId());
                resp.setType(PartyBuildingConstants.TodoType.PARTY_SURVEY_DEMOCRATIC_VOTING.getType());
                resp.setName(surveyDto.getPartySurveyName());
                resp.setStartTime(surveyDto.getPartySurveyStartTime());
                resp.setEndTime(surveyDto.getPartySurveyEndTime());
                resultList.add(resp);
            }
        });

        CompletableFuture.allOf(examTraining,threeMeetingsFuture, themePartyDayFuture, partyLifeMeetingFuture,
                partyActivityFuture, partyBuildingTaskFuture, partyCourses, publicOpinionSurvey, democraticVoting).join();

        return Response.<List<PartyBuildingTodoResp>>ok().wrap(resultList);
    }
}
